package core.process;

import core.utils.EPara;
import core.rb.MB;
import core.rb.PB;
import core.rb.r.MR;
import core.process.pack.AlignPack;
import core.sb.s.Seq;
import gui.processor.Processor;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;

/*Author: John Archer, Contact: john.archer.jpa@gmail.com*/
public class Align{
    protected MB mb;
    private Processor p;
    public Align(MB mb, Processor gp){this.mb = mb;this.p = gp;}
    public PB getAln() throws Exception {
        int size = (mb.getSize() / EPara.THREADS);
        int i = 0;
        ArrayList <MB> packs = new ArrayList();
        ArrayList <MR> pack;
        for(int x = 0; x<EPara.THREADS; x++){
            pack = new ArrayList();
            for(int y = 0; y<size; y++){pack.add(mb.getRead(i++));}
            packs.add(new MB(new Seq(mb.getRef().getTitle(), mb.getRef().getDNA()), pack));
        }
        MB fPack = packs.get(0);
        for(int x=i; x<mb.getSize(); x++){fPack.add(mb.getRead(i++));}
        AlignPack [] ap = new AlignPack[packs.size()];
        CountDownLatch cdl = new CountDownLatch(packs.size());
        for (int x = 0; x < packs.size(); x++) {
            if(x==0){ap[x] = new AlignPack(p, cdl, packs.get(x));}
            else{ap[x] = new AlignPack(null, cdl, packs.get(x));}
        }
        cdl.await();
        ArrayList <PB> combined = new ArrayList();
        for (int x = 0; x < ap.length; x++){combined.add(ap[x].getPOut());}
        PB pb = new PB(new Seq(new String(mb.getRef().getTitle()), new String(mb.getRef().getDNA())));
        PB temp;
        for (int x = 0; x < combined.size(); x++) {
            temp = combined.get(x);
            for(int y=0; y<temp.getSize();y++){pb.add(temp.getRead(y));}
        }
        return pb;
    }
}